package com.jungle.base.service.impl;

import cn.hutool.core.io.IoUtil;
import com.jungle.system.service.ISysOssService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.locationtech.jts.io.ParseException;
import org.springframework.stereotype.Service;
import org.ssssssss.magicapi.core.service.MagicAPIService;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 风险评估Service业务层处理
 *
 * @author jungle
 * @date 2023-08-20
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class YjFxpgServiceImpl {


    private final MagicAPIService service;

    private final ISysOssService sysOssService;


    public void genWordById(String id, HttpServletResponse response) throws IOException, ParseException {
//        YjFxpgVo fxpgVo = repository.findById(id).map(v -> BeanCopyUtils.copy(v, YjFxpgVo.class)).orElse(null);
//        //生成word
//        genWordMethod(fxpgVo, response);
        log.info("通过id生成word ...");
    }
/*

    private void genWordMethod(YjFxpgVo fxpgVo, HttpServletResponse response) throws IOException {
        fxpgVo.setPgsj(LocalDateTime.now());//评估时间
        fxpgVo.setFxpgid(String.valueOf(System.currentTimeMillis()));//风险评估id


        CustomCztTableRenderPolicy cztPolicy = new CustomCztTableRenderPolicy();
        CustomJzzyTableRenderPolicy jzzyPolicy = new CustomJzzyTableRenderPolicy(service);
        HashMap<String, Object> args = new HashMap<>() {
            {
                put("zdmc", fxpgVo.getZdmc());//站点名称
                put("zhlx", fxpgVo.getZhlx());//灾害类型
                put("glbm", fxpgVo.getGlbm());//管理部门
                put("zhxxdz", fxpgVo.getZhxxdz());//灾害详细地址
                put("fssj", Texts.of(LocalDateTimeUtil
                    .format(fxpgVo.getPgsj(), "yyyy年MM月dd日HH时mm分")).create());//发生时间
                put("yfys", fxpgVo.getYfys());//诱发因素
                put("wxhs", fxpgVo.getWxhs());//威胁户数
                put("wxrs", fxpgVo.getWxrs());//威胁人数
                put("wxcc", fxpgVo.getWxcc());//威胁财产
                put("yxrk", fxpgVo.getYxrk());//影响人口
                put("yxjj", fxpgVo.getYxjj());//影响经济
                put("yxfwsl", fxpgVo.getYxfwsl());//影响房屋数量
                put("yxntmj", fxpgVo.getYxntmj());//影响农田平方
                put("yxmjcssl", fxpgVo.getYxmjcssl());//影响密集场所个数
                put("jydwsl", fxpgVo.getJydwsl());  //救援队伍数量
                put("yjbncssl", fxpgVo.getYjbncssl());//应急避难场所数量
                put("wzcbksl", fxpgVo.getWzcbksl());//物资储备库数量

                int yjbnsfw = fxpgVo.getYjbnsfw() != null ? fxpgVo.getYjbnsfw().intValue() / 1000 : -1;
                put("yjbnsfw", yjbnsfw);//应急避难所范围(公里)
                int cztDistance = fxpgVo.getDistance() != null ? fxpgVo.getDistance().intValue() / 1000 : -1;
                put("distance", cztDistance);//距离参数(公里) 承载体

                int jydwDistance = fxpgVo.getJydwDistance() != null ? fxpgVo.getJydwDistance().intValue() / 1000 : -1;
                put("jydwDistance", jydwDistance);//救援队伍范围(公里)
                int wzcbkDistance = fxpgVo.getWzcbkDistance() != null ? fxpgVo.getWzcbkDistance().intValue() / 1000 : -1;
                put("wzcbkDistance", wzcbkDistance);//物资储备库范围(公里)

                //灾源geom
                Geometry sourceGeom = fxpgVo.getSourceGeom();

                //最近城镇信息
                YjFxpgRepository.NearestCityMsg nearestCityMsg = repository.nearestCity(sourceGeom);
                String jlzjcz = nearestCityMsg.getJgxxdz();
                fxpgVo.setJlzjcz(jlzjcz);
                Double minDistance = nearestCityMsg.getDistance() != null ? nearestCityMsg.getDistance() : 0;
                double zjczjlTmp = BigDecimal.valueOf(minDistance).setScale(2, RoundingMode.HALF_UP).doubleValue();
                fxpgVo.setZjczjl(zjczjlTmp);
                put("jlzjcz", jlzjcz);//距离最近成镇  ------  根据地点geom计算距离
                double zjczjl = BigDecimal.valueOf(zjczjlTmp / 1000).setScale(2, RoundingMode.HALF_UP).doubleValue();
                put("zjczjl", zjczjl);//最近城镇距离 （公里）
//                put("jlzjsh", fxpgVo.getShcs());//省会城市 ------  根据地点geom计算距离-------------
//                double sourceToShcsTmp = DistanceOp.distance(fxpgVo.getShcsGeom(), sourceGeom);
//                double sourceToShcs = BigDecimal.valueOf(sourceToShcsTmp).setScale(2, RoundingMode.HALF_UP).doubleValue();
//                fxpgVo.setShcsjl(sourceToShcs);
//                put("shjl", sourceToShcs);//与省会的距离（公里）

//                SysOssVo cztfbtSysOss = sysOssService.getById(Long.parseLong(fxpgVo.getCztfbt()));
//                SysOssVo cztfbtSysOss = sysOssService.getById(1693939868223733762L);
//                SysOssVo jydwfbtSysOss = sysOssService.getById(1693940649173778433L);
//                SysOssVo yjbnsfbtSysOss = sysOssService.getById(1693941069606617090L);
//                SysOssVo wzcbkfbtSysOss = sysOssService.getById(1693941178662715393L);
//                if (fxpgVo.getCztfbt() != null)
                put("cztfbt", Pictures.ofBase64(fxpgVo.getCztfbt() == null ? "" : fxpgVo.getCztfbt(), PictureType.JPEG).size(530, 300).create());//承灾体分布图
//                if (fxpgVo.getJydwfbt() != null)
                put("jydwfbt", Pictures.ofBase64(fxpgVo.getJydwfbt() == null ? "" : fxpgVo.getJydwfbt(), PictureType.JPEG).size(530, 300).create());//救援队伍分布图
//                if (fxpgVo.getYjbnsfbt() != null)
                put("yjbnsfbt", Pictures.ofBase64(fxpgVo.getYjbnsfbt() == null ? "" : fxpgVo.getYjbnsfbt(), PictureType.JPEG).size(530, 300).create());//应急避难场所分布图
//                if (fxpgVo.getWzcbkfbt() != null)
                put("wzcbkfbt", Pictures.ofBase64(fxpgVo.getWzcbkfbt() == null ? "" : fxpgVo.getWzcbkfbt(), PictureType.JPEG).size(530, 300).create());//物资储备库分布图
// 表格
                //范围(米)
                Double distance = fxpgVo.getDistance();
//
//                //50公里内的承灾体
//                List<YjCztjcbVo> cztList = repository.selectRangeCzt(distance, sourceGeom).stream()
//                    .map(v -> BeanCopyUtils.copy(v, YjCztjcbVo.class))
//                    .collect(Collectors.toList());
//
//                //根据承灾体小类分组
//                Map<String, List<YjCztjcbVo>> groupCzt = new HashMap<>();
//                for (YjCztjcbVo cztjcbVo : cztList) {
//                    if (cztjcbVo.getCztxl() != null)
//                        groupCzt.computeIfAbsent(cztjcbVo.getCztxl(), k -> new ArrayList<>()).add(cztjcbVo);
//                }
//                Set<String> allCztxl = groupCzt.keySet();
//                //影响范围统计
//                List<XlCount> cztxlList = new ArrayList<>();
//                //每个承灾体小类的统计信息
//                for (String xlmc : allCztxl) {
//                    //添加统计信息
//                    XlCount xl = new XlCount();
//                    xl.setCztxl(xlmc);
//                    xl.setUnit("处");
//                    List<YjCztjcbVo> list = groupCzt.get(xlmc);
//                    xl.setCount((long) list.size());
//                    cztxlList.add(xl);
//
//                    //计算每个承灾体和灾源的距离
//                    for (YjCztjcbVo yjCztjcbVo : list) {
//                        //当前承灾体位置 和 灾源位置的距离
//                        if (yjCztjcbVo.getGeom() != null) {
//                            yjCztjcbVo.setJl(DistanceOp.distance(yjCztjcbVo.getGeom(), sourceGeom));
//                        }
//                    }
//                }
//                //设置要添加的内容
//                put("cztMsg", groupCzt);//该小类的所有承灾体
//                //循环表格行
//                put("xlList", cztxlList);//统计所有承灾体小类信息
//
//                //查范围内的减灾资源-------------
//
//                List<YjJzzyVo> jzzyList = repository.selectRangeJzzy(distance, sourceGeom).stream()
//                    .map(v -> BeanCopyUtils.copy(v, YjJzzyVo.class))
//                    .collect(Collectors.toList());
//                //根据减灾资源小类分组
//                Map<String, List<YjJzzyVo>> groupJzzy = new HashMap<>();
//                for (YjJzzyVo jzzyVo : jzzyList) {
//                    if (jzzyVo.getJzzyxl() != null)
//                        groupJzzy.computeIfAbsent(jzzyVo.getJzzyxl(), k -> new ArrayList<>()).add(jzzyVo);
//                }
//
//                //设置每个减灾资源的距离
//                for (YjJzzyVo jzzy : jzzyList) {
//                    if (jzzy.getGeom() != null) {
//                        //当前承灾体位置 和 灾源位置的距离
//                        jzzy.setJl(DistanceOp.distance(jzzy.getGeom(), sourceGeom));
//                    }
//                }
//                put("jzzyMsg", groupJzzy);
            }
        };

        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        Configure config = Configure.builder()
            .bind("xlList", policy)//小类信息集合
            .bind("cztMsg", cztPolicy)
            .bind("jzzyMsg", jzzyPolicy)
            .build();

        //获取模板文件
        Long ossid = (Long) service.invoke("/rules/templateFile", null);
        SysOssVo wordTemplate = sysOssService.getById(ossid);
        String url = wordTemplate.getUrl();
        log.info("----下载模板文件：{}", url);
        byte[] bytes = HttpUtil.downloadBytes(url);
        log.info("----下载完毕：{}", url);
        InputStream is = new ByteArrayInputStream(bytes);
        XWPFTemplate template = XWPFTemplate.compile(is, config).render(args);

        XWPFDocument document = template.getXWPFDocument();

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        document.write(outputStream);
        byte[] genWordBytes = outputStream.toByteArray();

//        template.writeAndClose(new FileOutputStream(dest + "\\" + fxpgVo.getZdmc() + fxpgVo.getZhlx() + "灾害报告.docx"));

        genCode(response, genWordBytes, fxpgVo.getZdmc() + fxpgVo.getZhlx() + "灾害报告");

        log.info("风险评估报告生成完毕~请下载");
    }
*/


    private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");

    /**
     * 生成word文件
     */
    private void genCode(HttpServletResponse response, byte[] data, String fileName) throws IOException {
        response.reset();
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
        // 对文件名进行URL编码
        String wordFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);

        response.setHeader("Content-Disposition", "attachment; filename=\"" + wordFileName + "-" + simpleDateFormat.format(new Date()) + ".docx\"");
        response.addHeader("Content-Length", "" + data.length);
//        response.setContentType("application/octet-stream; charset=UTF-8");
        IoUtil.write(response.getOutputStream(), false, data);
    }
}
